package com.zzyl.serve.service.impl;

import java.time.LocalDateTime;
import java.util.*;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.serve.domain.PageDto;
import com.zzyl.serve.domain.PageResult;
import com.zzyl.serve.vo.CountByTimeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.zzyl.serve.mapper.ReservationMapper;
import com.zzyl.serve.domain.Reservation;
import com.zzyl.serve.service.IReservationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.function.Consumer;

/**
 * 预约信息Service业务层处理
 * 
 * @author huangqin
 * @date 2025-05-08
 */

@Service
public class ReservationServiceImpl extends ServiceImpl<ReservationMapper, Reservation> implements IReservationService {
    @Autowired
    private ReservationMapper reservationMapper;
    
    /**
     * 查询预约信息
     *
     * @return 预约信息
     */
    @Override
    public Long getCancelledCount() {
        long time = System.currentTimeMillis();
        LocalDateTime ldt = LocalDateTimeUtil.of(time);
        LocalDateTime startTime = ldt.toLocalDate().atStartOfDay();
        LocalDateTime endTime = startTime.plusDays(1);
        LambdaQueryWrapper<Reservation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.between(Reservation::getUpdateTime, startTime, endTime);
        queryWrapper.eq(Reservation::getStatus, 2);
        Long count = Long.valueOf(this.count(queryWrapper));
        return count;
    }

/**
 * 查询每个时间段剩余预约次数
 *
 * @return
 */
@Override
public List<CountByTimeVo> countByTime(long time) {
    LocalDateTime localDateTime1 = LocalDateTimeUtil.of(time);
    LocalDateTime ldt = localDateTime1.plusHours(8);
    ArrayList<CountByTimeVo> countByTimeVos = new ArrayList<>();
    for (int i=0;i<=20;i++,ldt = ldt.plusMinutes(30)){
        LocalDateTime startTime = ldt.minusMinutes(1);
        LocalDateTime endTime = ldt.plusMinutes(1);
        CountByTimeVo countByTimeVo =reservationMapper.countByTime(ldt,startTime,endTime);
        countByTimeVos.add(countByTimeVo);
    }
    Iterator<CountByTimeVo> iterator = countByTimeVos.iterator();
    while (iterator.hasNext()){
        CountByTimeVo next = iterator.next();
        if (ObjectUtil.isEmpty(next)){
            iterator.remove();
        }
    }
    return countByTimeVos;
}

/**
 * 新增预约信息
 *
 * @param reservation 预约信息
 */
@Override
public void saveReservation(Reservation reservation) {
    List<Reservation> list = this.list(new LambdaQueryWrapper<Reservation>().eq(Reservation::getTime, reservation.getTime()));
    if (list.size()>=6){
        throw new RuntimeException("预约时间段已满");
    }
    Long cancelledCount = this.getCancelledCount();
    if (cancelledCount>3){
        throw new RuntimeException("取消次数超过三次，无法预约！");
    }
    reservation.setStatus(0);
    this.save(reservation);
}

/**
 * 查询预约信息
 *
 * @param pageDto
 * @return 预约信息
 */
@Override
public PageResult listService(PageDto pageDto) {
    PageHelper.startPage(pageDto.getPageNum(), pageDto.getPageSize());
    LambdaQueryWrapper<Reservation> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(pageDto.getStatus() != null, Reservation::getStatus, pageDto.getStatus());
    List<Reservation> list = this.list(queryWrapper);
    Page<Reservation> page = (Page<Reservation>) list;
    PageResult pageResult = new PageResult();
    pageResult.setTotal(page.getTotal());
    pageResult.setRows(page.getResult());
    
    return pageResult;
}

/**
 * 取消预约
 * @param id
 */
@Override
public void cancelReservation(Long id) {
    LambdaQueryWrapper<Reservation> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(Reservation::getId, id);
    Reservation reservation = this.getOne(queryWrapper);
    reservation.setStatus(2);
    this.updateById(reservation);
}


@Override
public void updateReservationStatus() {
    LambdaQueryWrapper<Reservation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    lambdaQueryWrapper.eq(Reservation::getStatus, 0);
    lambdaQueryWrapper.le(Reservation::getTime, LocalDateTime.now());
    List<Reservation> list = this.list(lambdaQueryWrapper);
    list.forEach(reservation -> {
        if (LocalDateTime.now().isAfter(reservation.getTime())){
            reservation.setStatus(3);
            reservationMapper.updateById(reservation);
        }
    });
}
}
